﻿#include "AbsFrameLessAutoSize.h"
#include <QMouseEvent>
#include <QCursor>
#include <QDebug>

AbsFrameLessAutoSize::AbsFrameLessAutoSize(QWidget *parent)
    : QWidget(parent),
      m_isForbidDrag(false)
{
    m_bIsLeftPressDown = false;
    this->m_dir = NONE;
    //this->resize(360,660);
    //this->setMinimumSize(400,700);
    //this->setMaximumSize(720,920);
    this->setWindowFlags(Qt::FramelessWindowHint);
    this->setMouseTracking(true);     //默认按下鼠标按键时拖动才会产生移动事件，设置为true以后实时追踪移动事件
}

void AbsFrameLessAutoSize::mousePressEvent(QMouseEvent *event)
{
    //qDebug() << "AbsFrameLessAutoSize::mousePressEvent";
    //this->setFocus();
    if(event->button() == Qt::LeftButton)
    {
        m_bIsLeftPressDown = true;
        if(m_dir != NONE) {
            this->mouseGrabber();
        } else {
            m_dragPosition = event->globalPos() - this->pos();
        }
    }
}

void AbsFrameLessAutoSize::mouseReleaseEvent(QMouseEvent *event)
{
    //qDebug() << "AbsFrameLessAutoSize::mouseReleaseEvent";
    if(event->button() == Qt::LeftButton) {
        m_bIsLeftPressDown = false;
        if(m_dir != NONE) {
            this->releaseMouse();
            this->setCursor(QCursor(Qt::ArrowCursor));
        }
    }
}

void AbsFrameLessAutoSize::mouseMoveEvent(QMouseEvent *event)
{
    //qDebug() << "AbsFrameLessAutoSize::mouseMoveEvent :" << m_bIsLeftPressDown;
    //QPoint gloPoint = mapToGlobal(event->pos());
    //QPoint gloPoint = event->globalPos();
    if(m_isForbidDrag)
        return;
    QPoint gloPoint = QCursor::pos();
    QRect rect = this->rect();
    QPoint tl = mapToGlobal(rect.topLeft());
    QPoint rb = mapToGlobal(rect.bottomRight());

    if(!m_bIsLeftPressDown)
    {
        this->region(gloPoint);
    }else
    {
        //this->setFocus();
        if(m_dir != NONE)
        {
            QRect rMove(tl, rb);

            switch(m_dir) {
            case LEFT:
                if((rb.x() - gloPoint.x() <= this->minimumWidth()))
                    rMove.setX(rb.x()-this->minimumWidth()+1);
                else if((rb.x() - gloPoint.x() >= this->maximumWidth()))
                    //rMove.setX(tl.x());
                    //实测发现rb.x()-tl.x() = width()-1,因此下面加1
                    rMove.setX(rb.x()-this->maximumWidth()+1);
                else
                    rMove.setX(gloPoint.x());
                break;
            case RIGHT:
                rMove.setWidth(gloPoint.x() - tl.x());
                break;
            case UP:
                if(rb.y() - gloPoint.y() <= this->minimumHeight() ||
                        rb.y() - gloPoint.y() >= this->maximumHeight())
                    rMove.setY(tl.y());
                else
                    rMove.setY(gloPoint.y());
                break;
            case DOWN:
                rMove.setHeight(gloPoint.y() - tl.y());
                break;
            case LEFTTOP:
                if((rb.x() - gloPoint.x() <= this->minimumWidth()) ||
                        (rb.x() - gloPoint.x() >= this->maximumWidth()))
                    rMove.setX(tl.x());
                else
                    rMove.setX(gloPoint.x());
                if(rb.y() - gloPoint.y() <= this->minimumHeight() ||
                        rb.y() - gloPoint.y() >= this->maximumHeight())
                    rMove.setY(tl.y());
                else
                    rMove.setY(gloPoint.y());
                break;
            case RIGHTTOP:
                rMove.setWidth(gloPoint.x() - tl.x());
                if(rb.y() - gloPoint.y() <= this->minimumHeight() ||
                        rb.y() - gloPoint.y() >= this->maximumHeight())
                    rMove.setY(tl.y());
                else
                    rMove.setY(gloPoint.y());
                break;
            case LEFTBOTTOM:
                if((rb.x() - gloPoint.x() <= this->minimumWidth()) ||
                        (rb.x() - gloPoint.x() >= this->maximumWidth()))
                    rMove.setX(tl.x());
                else
                    rMove.setX(gloPoint.x());
                rMove.setHeight(gloPoint.y() - tl.y());
                break;
            case RIGHTBOTTOM:
                rMove.setWidth(gloPoint.x() - tl.x());
                rMove.setHeight(gloPoint.y() - tl.y());
                break;
            default:

                break;
            }
            this->setGeometry(rMove);
        }
        else
        {
            move(event->globalPos() - m_dragPosition);
            event->accept();
        }
    }
    //m_bIsLeftPressDown = false
}

void AbsFrameLessAutoSize::region(const QPoint &cursorGlobalPoint)
{
    QRect rect = this->rect();
    QPoint tl = mapToGlobal(rect.topLeft());
    QPoint rb0 = mapToGlobal(rect.bottomRight());
    QPoint rb = QPoint(rb0.x()+1,rb0.y()+1);
    int x = cursorGlobalPoint.x();
    int y = cursorGlobalPoint.y();

    if(tl.x() + PADDING >= x && tl.x() <= x && tl.y() + PADDING >= y && tl.y() <= y) {
        // 左上角
        m_dir = LEFTTOP;
        this->setCursor(QCursor(Qt::SizeFDiagCursor));
    } else if(x >= rb.x() - PADDING && x <= rb.x() && y >= rb.y() - PADDING && y <= rb.y()) {
        // 右下角
        m_dir = RIGHTBOTTOM;
        this->setCursor(QCursor(Qt::SizeFDiagCursor));
    } else if(x <= tl.x() + PADDING && x >= tl.x() && y >= rb.y() - PADDING && y <= rb.y()) {
        //左下角
        m_dir = LEFTBOTTOM;
        this->setCursor(QCursor(Qt::SizeBDiagCursor));
    } else if(x <= rb.x() && x >= rb.x() - PADDING && y >= tl.y() && y <= tl.y() + PADDING) {
        // 右上角
        m_dir = RIGHTTOP;
        this->setCursor(QCursor(Qt::SizeBDiagCursor));
    } else if(x <= tl.x() + PADDING && x >= tl.x()) {
        // 左边
        m_dir = LEFT;
        this->setCursor(QCursor(Qt::SizeHorCursor));
    } else if( x <= rb.x() && x >= rb.x() - PADDING) {
        // 右边
        m_dir = RIGHT;
        this->setCursor(QCursor(Qt::SizeHorCursor));
    }else if(y >= tl.y() && y <= tl.y() + PADDING){
        // 上边
        m_dir = UP;
        this->setCursor(QCursor(Qt::SizeVerCursor));
    } else if(y <= rb.y() && y >= rb.y() - PADDING) {
        // 下边
        m_dir = DOWN;
        this->setCursor(QCursor(Qt::SizeVerCursor));
    }else {
        // 默认
        m_dir = NONE;
        this->setCursor(QCursor(Qt::ArrowCursor));
    }
}

